package de.westranger.forex.trading.analysis;

import java.awt.Shape;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.List;
import java.util.Stack;
import java.util.zip.GZIPInputStream;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.util.ShapeUtilities;

import de.westranger.forex.trading.GlobalConfig;
import de.westranger.forex.trading.genetic.CSVBasedContentResolver;
import de.westranger.forex.trading.genetic.ContentResolver;
import de.westranger.forex.trading.genetic.allel.Node;
import de.westranger.forex.trading.genetic.allel.chromosom.CompositeChromosom;
import de.westranger.forex.trading.genetic.allel.fitness.CompositeFitness;
import de.westranger.forex.trading.genetic.allel.fitness.ComputeFitness;
import de.westranger.forex.trading.genetic.allel.fitness.MoneyManagedFitness;
import de.westranger.forex.trading.genetic.allel.operator.TerminalSymbol;
import de.westranger.forex.trading.genetic.allel.operator.UnknownOperatorException;
import de.westranger.forex.trading.genetic.allel.operator.Util;

public final class TradingRuleValidation {

	private static final String[] tradingRule = new String[] {
			".\\out\\wkt8_6_result.ser"};
	
	private static final String[] validationFiles1 = new String[] {
			"E:\\EUR_USD_2012\\indicator\\01_EUR_USD_Week1_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\01_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\01_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\01_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\01_EUR_USD_Week5_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\02_EUR_USD_Week1_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\02_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\02_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\02_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\03_EUR_USD_Week1_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\03_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\03_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\03_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\04_EUR_USD_Week1_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\04_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\04_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\04_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\04_EUR_USD_Week5_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\05_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\05_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\05_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\05_EUR_USD_Week5_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\06_EUR_USD_Week1_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\06_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\06_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\06_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\07_EUR_USD_Week1_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\07_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\07_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\07_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\07_EUR_USD_Week5_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\08_EUR_USD_Week1_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\08_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\08_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\08_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\09_EUR_USD_Week1_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\09_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\09_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\09_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\10_EUR_USD_Week1_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\10_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\10_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\10_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\10_EUR_USD_Week5_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\11_EUR_USD_Week1_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\11_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\11_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\11_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\12_EUR_USD_Week1_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\12_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\12_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\12_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2012\\indicator\\12_EUR_USD_Week5_indicator.csv",
			"E:\\EUR_USD_2013\\indicator\\01_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2013\\indicator\\01_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2013\\indicator\\01_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2013\\indicator\\01_EUR_USD_Week5_indicator.csv",
			"E:\\EUR_USD_2013\\indicator\\02_EUR_USD_Week1_indicator.csv",
			"E:\\EUR_USD_2013\\indicator\\02_EUR_USD_Week2_indicator.csv",
			"E:\\EUR_USD_2013\\indicator\\02_EUR_USD_Week3_indicator.csv",
			"E:\\EUR_USD_2013\\indicator\\02_EUR_USD_Week4_indicator.csv",
			"E:\\EUR_USD_2013\\indicator\\03_EUR_USD_Week1_indicator.csv",
			"E:\\EUR_USD_2013\\indicator\\03_EUR_USD_Week2_indicator.csv"};
	
	
	private static final String[] validationFiles2 = new String[] {
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_0.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_1.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_2.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_3.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_4.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_5.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_6.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_7.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_8.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_9.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_10.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_11.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_12.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_13.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_14.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_15.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_16.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_17.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_18.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_19.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_20.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_21.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_22.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_23.csv.gz"};
	
	private static final String[] validationFiles3 = new String[] {
		"E:\\EUR_USD_2012\\indicator_wk1\\mql_validation_java_indicator_0.csv.gz",
		"E:\\EUR_USD_2012\\indicator_wk1\\mql_validation_java_indicator_1.csv.gz",
		"E:\\EUR_USD_2012\\indicator_wk1\\mql_validation_java_indicator_2.csv.gz",
		"E:\\EUR_USD_2012\\indicator_wk1\\mql_validation_java_indicator_3.csv.gz",
		"E:\\EUR_USD_2012\\indicator_wk1\\mql_validation_java_indicator_4.csv.gz",
		"E:\\EUR_USD_2012\\indicator_wk1\\mql_validation_java_indicator_5.csv.gz",
		"E:\\EUR_USD_2012\\indicator_wk1\\mql_validation_java_indicator_6.csv.gz",
		"E:\\EUR_USD_2012\\indicator_wk1\\mql_validation_java_indicator_7.csv.gz",
		"E:\\EUR_USD_2012\\indicator_wk1\\mql_validation_java_indicator_8.csv.gz",
		"E:\\EUR_USD_2012\\indicator_wk1\\mql_validation_java_indicator_9.csv.gz",
		"E:\\EUR_USD_2012\\mql\\mql_validation_java_indicator_0.csv.gz"};
	
	private static final String[] validationFiles4 = new String[] {
		"E:\\EUR_USD_2012\\indicator_wk1\\mql_validation_java_indicator_1.csv.gz"};
	
	private static final String[] validationFiles5 = new String[] {
		".\\data\\mql_validation_java_indicator_22.csv.gz"};

	private static final String[] validationFiles6 = new String[] {
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_1.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_2.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_3.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_4.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_5.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_6.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_7.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_8.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_9.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_10.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_11.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_12.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_13.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_14.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_15.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_16.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_17.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_18.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_19.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_20.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_21.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_22.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_23.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_24.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_25.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_26.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_27.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_28.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_29.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_30.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_31.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_32.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_33.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_34.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_35.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_36.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_37.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_38.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_39.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_40.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_41.csv.gz",
		"F:\\Program Files (x86)\\OANDA - MetaTrader\\tester\\files\\mt4_validation_mql_indicator_42.csv.gz"};

	private static final String[] validationFiles7 = new String[] {
		".\\data\\mt4_validation_mql_indicator_1.csv.gz",
		".\\data\\mt4_validation_mql_indicator_2.csv.gz",
		".\\data\\mt4_validation_mql_indicator_3.csv.gz",
		".\\data\\mt4_validation_mql_indicator_4.csv.gz",
		".\\data\\mt4_validation_mql_indicator_5.csv.gz",
		".\\data\\mt4_validation_mql_indicator_6.csv.gz",
		".\\data\\mt4_validation_mql_indicator_7.csv.gz",
		".\\data\\mt4_validation_mql_indicator_8.csv.gz"};
	
	private static final String[] validationFiles666 = new String[] {
			"E:\\MT4_vlidation_data\\ema_train_0.csv.gz",
			"E:\\MT4_vlidation_data\\ema_train_1.csv.gz",
			"E:\\MT4_vlidation_data\\ema_train_2.csv.gz",
			"E:\\MT4_vlidation_data\\ema_train_3.csv.gz",
			"E:\\MT4_vlidation_data\\ema_train_4.csv.gz",
			"E:\\MT4_vlidation_data\\ema_train_5.csv.gz",
			"E:\\MT4_vlidation_data\\ema_train_6.csv.gz",
			"E:\\MT4_vlidation_data\\ema_train_7.csv.gz",
			"E:\\MT4_vlidation_data\\ema_train_8.csv.gz",
			"E:\\MT4_vlidation_data\\ema_train_9.csv.gz",
			"E:\\MT4_vlidation_data\\ema_train_10.csv.gz",
			"E:\\MT4_vlidation_data\\ema_train_11.csv.gz",
			"E:\\MT4_vlidation_data\\ema_train_12.csv.gz" };
	
	private static final int width = 800;
	private static final int height = 450;
	
	public static void main(String[] args) {
		System.out.println("start validation");
		CompositeChromosom[] chrom = new CompositeChromosom[tradingRule.length];
		final Stack<CompositeFitness> resultList = new Stack<CompositeFitness>();
		final Stack<Integer> lineList = new Stack<Integer>();
		
		for(int i=0;i<chrom.length;i++){
			try{
				final FileInputStream fis = new FileInputStream(tradingRule[i]);
			    final ObjectInputStream ois = new ObjectInputStream(fis);
			    chrom[i] = (CompositeChromosom) ois.readObject();
			    ois.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}			
		}

//		chrom.setStoploss(6);
//		chrom.setTakeProfit(27);	

		final StringBuilder sb = new StringBuilder();
		sb.append("<html>");
		sb.append("<head>");
		sb.append("<title>");
		sb.append("Validation of Trading-Rule");
		sb.append("</title>");
		sb.append("</head>");
		sb.append("<body>");
		sb.append("<h2>Parameter:</h2>");
		sb.append("<ul>");
		sb.append("<li>stop-loss: ");
		sb.append(chrom[0].getStoploss());
		sb.append("</li>");
		sb.append("<li>take profit: ");
		sb.append(chrom[0].getTakeProfit());
		sb.append("</li>");
		sb.append("<li>trading start hour: ");
		sb.append(chrom[0].getTradingStartHour());
		sb.append("</li>");
		sb.append("<li>trading end hour");
		sb.append(chrom[0].getTradingEndHour());
		sb.append("</li>");
		sb.append("<li>Eingesetztes Kapital: ");
		sb.append(GlobalConfig.MONEY);
		sb.append("</li>");
		sb.append("<li>Einsatz pro Trade: ");
		sb.append(GlobalConfig.MONEY_INVEST);
		sb.append("</li>");
		sb.append("<li>Hebel: ");
		sb.append(GlobalConfig.LEVERAGE);
		sb.append("</li>");
		sb.append("</ul>");

		
		sb.append("<table border=\"1\" cellpadding=\"2\">");
		sb.append("<tr><th></th>");
		for(TerminalSymbol ts:TerminalSymbol.values()){
			sb.append("<th>");
			sb.append(ts.name());
			sb.append("</th>");
		}
		sb.append("</tr>");
		sb.append("<tr><td></td>");					
		List<Node> nodes = Util.getQueryNodes(chrom[0].getNodeBuy(), Util.QUERY_TERMINALS);
		for(TerminalSymbol ts:TerminalSymbol.values()){
			sb.append("<td>");
			for(Node n:nodes){
				if(n.getValue() == ts.getValue()){
					sb.append("X");
					break;
				}
			}
			sb.append("</td>");			
		}
		sb.append("</tr>");
		sb.append("</table><br><br>");
		
		sb.append("<table border=\"1\" cellpadding=\"2\">");
		sb.append("<tr>");
		sb.append("<th>Dateiname</th>");
		sb.append("<th># Zeilen</th>");
		sb.append("<th>Profit in &euro;</th>");
		sb.append("<th>&Oslash;pos. Profit</th>");
		sb.append("<th>&Oslash;neg. Profit</th>");
		sb.append("<th># pos. Trade</th>");
		sb.append("<th># neg. Trade</th>");
		sb.append("<th># Stop-Loss</th>");
		sb.append("<th># Take Profit</th>");
		sb.append("<th># Buy positions</th>");
		sb.append("<th># Sell Positions</th>");
		sb.append("</tr>");

		for(String file:validationFiles7){
			try {
				System.out.println("validiere mit Datei: " + file);
//				if(chrom.length == 1){
					resultList.add(validate(chrom[0],file));					
//				}else{
//					resultList.add(validate(chrom,file));
//				}

				int numLines = getNumLines(file);
				lineList.push(numLines);
				final String result = fitnessToHTML(resultList.peek(),file,numLines);
				System.out.println(result);
				sb.append(result);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ParseException e) {
				e.printStackTrace();
			} catch (UnknownOperatorException e) {
				e.printStackTrace();
			}
		}
		sb.append("</table>");
		
		//#################################################################
		float[][] data = new float[2][resultList.size()];
		for(int i=0;i<resultList.size();i++){
			data[0][i] = (float)resultList.elementAt(i).getAvgNegProfit();
			data[1][i] = (float)resultList.elementAt(i).getAvgPosProfit();
		}

		File file = new File(".\\report\\avg_profit.jpg");
		writeScatterPlot("positive vs negative profit",data,"negative profit", "positive profit",file);
		sb.append("<img src=\"avg_profit.jpg\"width=\""+width+"\" height=\""+height+"\"><br>");
		
		//#################################################################
		data = new float[2][resultList.size()];
		for(int i=0;i<resultList.size();i++){
			data[0][i] = (float)resultList.elementAt(i).getAvgNegProfit()*(float)resultList.elementAt(i).getNegTrade();
			data[1][i] = (float)resultList.elementAt(i).getAvgPosProfit()*(float)resultList.elementAt(i).getPosTrade();
		}

		file = new File(".\\report\\profit_vs_loss.jpg");
		writeScatterPlot("total profit vs total loss",data,"total loss", "total profit",file);
		sb.append("<img src=\"profit_vs_loss.jpg\"width=\""+width+"\" height=\""+height+"\"><br>");

		//#################################################################
		data = new float[2][resultList.size()];
		for(int i=0;i<resultList.size();i++){
			data[0][i] = (float)lineList.elementAt(i);
			data[1][i] = (float)resultList.elementAt(i).getProfit();
		}

		file = new File(".\\report\\lines_vs_profit.jpg");
		writeScatterPlot("number of lines vs total profit",data,"number of lines", "total profit",file);
		sb.append("<img src=\"lines_vs_profit.jpg\"width=\""+width+"\" height=\""+height+"\"><br>");

		//#################################################################		
		sb.append("</body>");
		sb.append("</html>");

		try {
			final BufferedWriter bw = new BufferedWriter(new FileWriter("./report/validation.html"));
			bw.write(sb.toString());
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		System.out.println("validation done");
	}

	private static CompositeFitness validate(final CompositeChromosom chrom, final String file) throws IOException, ParseException, UnknownOperatorException{
		final ContentResolver cr = new CSVBasedContentResolver(file);		
		System.out.println("read file done");
		final ComputeFitness ccf = new MoneyManagedFitness(cr,GlobalConfig.MONEY,GlobalConfig.MONEY_INVEST,GlobalConfig.LEVERAGE);
		final CompositeFitness cf = ccf.computeFitness(chrom);
		return cf;
	}
	
//	private static CompositeFitness validate(final CompositeChromosom[] chrom, final String file) throws IOException, ParseException, UnknownOperatorException{
//		final ContentResolver cr = new CSVBasedContentResolver(file);		
//		System.out.println("read file done");
//		final MoneyManagedFitness ccf = new MoneyManagedFitness(cr,GlobalConfig.MONEY,GlobalConfig.MONEY_INVEST,GlobalConfig.LEVERAGE);
//		final CompositeFitness cf = ccf.computeFitness(chrom);
//		return cf;
//	}
	
	private static String fitnessToHTML(final CompositeFitness cf, final String file,final int numLines){
		final StringBuilder sb = new StringBuilder();
		final DecimalFormat df = new DecimalFormat( "###,##0.00" );
		
		final String[] tmp = file.split("\\\\");
		
		sb.append("<tr><td align=\"right\">");
		sb.append(tmp[tmp.length-1]);
		sb.append("</td><td align=\"right\">");
		sb.append(numLines);
		sb.append("</td><td align=\"right\">");
		sb.append(df.format(cf.getProfit()));
		sb.append("</td><td align=\"right\">");
		sb.append(df.format(cf.getAvgPosProfit()));
		sb.append("</td><td align=\"right\">");
		sb.append(df.format(cf.getAvgNegProfit()));
		sb.append("</td><td align=\"right\">");
		sb.append(df.format(cf.getPosTrade()));
		sb.append("</td><td align=\"right\">");
		sb.append(df.format(cf.getNegTrade()));
		sb.append("</td><td align=\"right\">");
		sb.append(cf.getCounterStopLoss());
		sb.append("</td><td align=\"right\">");
		sb.append(cf.getCounterTakeProfit());
		sb.append("</td><td align=\"right\">");
		sb.append(cf.getCounterBuy());
		sb.append("</td><td align=\"right\">");
		sb.append(cf.getCounterSell());
		sb.append("</td></tr>");
		
		return sb.toString();		
	}

	private static final int getNumLines(final String file){
		int counter = 0;
		try{			
			BufferedReader br;
			if(file.endsWith(".csv.gz")){
				br = new BufferedReader(new InputStreamReader(new GZIPInputStream(new BufferedInputStream(new FileInputStream(file)))));
			}else{
				br = new BufferedReader(new FileReader(file));
			}
			
			
			while(br.ready()){
				br.readLine();
				counter++;
			}

			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return counter;
	}

	//	final ChromosomPrinter chromPrint = new ChromosomPrinter();
	//	FileWriter fw = new FileWriter("./out/omni_sell.txt");
	//	fw.append(chromPrint.generateGraphVIZ(((CompositeChromosom)in).getNodeSell()));
	//	fw.close();
	//	fw = new FileWriter("./out/omni_buy.txt");
	//	fw.append(chromPrint.generateGraphVIZ(((CompositeChromosom)in).getNodeBuy()));
	//	fw.close();
	
	private static void writeScatterPlot(final String title,float[][] data,final String xTitle, final String yTitle,final File file){
		final NumberAxis domainAxis = new NumberAxis(xTitle);
        domainAxis.setAutoRangeIncludesZero(false);
        final NumberAxis rangeAxis = new NumberAxis(yTitle);
        rangeAxis.setAutoRangeIncludesZero(false);

        final JFreeChart chart = ChartFactory.createScatterPlot(title, xTitle, yTitle, xyDataSet(data), PlotOrientation.VERTICAL, true, true, false);

        final Shape cross = ShapeUtilities.createDiagonalCross(3, 1);
        final XYPlot plot1 = (XYPlot) chart.getPlot();
        final XYItemRenderer renderer = plot1.getRenderer();
        renderer.setSeriesShape(0, cross);
        try {
			ChartUtilities.saveChartAsJPEG(file, chart, width, height);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private static XYDataset xyDataSet(final float[][] data) {
        final XYSeriesCollection xySeriesCollection = new XYSeriesCollection();
        final XYSeries series = new XYSeries("Random");

        for (int i = 0; i < data[0].length; i++) {
        	series.add(data[0][i], data[1][i]);
        }

        xySeriesCollection.addSeries(series);
        return xySeriesCollection;
    }
}
